import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar
import matplotlib.font_manager as fm
import matplotlib.patches as mpatches
from scipy.interpolate import griddata


plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
# 加载数据
data = pd.read_csv('./boston.csv')

# 设置图片清晰度
plt.rcParams['figure.dpi'] = 300

# 生成模拟坐标
data['longitude'] = data['DIS']
data['latitude'] = data['RAD']

# 准备等高线数据
xi = np.linspace(data['longitude'].min(), data['longitude'].max(), 100)
yi = np.linspace(data['latitude'].min(), data['latitude'].max(), 100)
xi, yi = np.meshgrid(xi, yi)
zi = griddata((data['longitude'], data['latitude']), data['MEDV'], (xi, yi), method='cubic')

# 创建一个更美观的地形图配色方案
topo_cmap = LinearSegmentedColormap.from_list('topo_cmap',
                                               [(0, '#006400'), (0.2, '#228B22'), (0.4, '#32CD32'),
                                                (0.6, '#98FB98'), (0.8, '#FFFFE0'), (1, '#FFD700')])

# 创建图形和坐标轴
fig, ax = plt.subplots(figsize=(10, 8))

# 绘制 15 级等高线，间隔颜色区分
contour = ax.contourf(xi, yi, zi, levels=15, cmap=topo_cmap, alpha=0.8)
ax.contour(xi, yi, zi, levels=15, colors='gray', linewidths=0.5)

# 叠加原始数据点半透明显示，调整点的大小和透明度
ax.scatter(data['longitude'], data['latitude'], c='black', alpha=0.2, s=8)

# 标注查尔斯河和市中心位置（这里假设简单的位置，实际应根据数据含义调整）
ax.text(data['longitude'].mean(), data['latitude'].max(), '查尔斯河', ha='center', va='bottom', color='navy', fontsize=10)
ax.text(data['longitude'].min(), data['latitude'].mean(), '市中心', ha='left', va='center', color='maroon', fontsize=10)

# 添加比例尺
fontprops = fm.FontProperties(size=12)
scalebar = AnchoredSizeBar(ax.transData,
                           1, '1 单位', 'lower right',
                           pad=0.1,
                           color='black',
                           frameon=True,
                           size_vertical=0.05,
                           fontproperties=fontprops)
ax.add_artist(scalebar)

# 添加指北针
arrow = mpatches.FancyArrowPatch((0.1, 0.9), (0.1, 0.95), transform=ax.transAxes, color='black',
                                 arrowstyle='->,head_width=0.05,head_length=0.1', mutation_scale=20)
ax.add_patch(arrow)
ax.text(0.08, 0.92, '北', transform=ax.transAxes, fontsize=12, color='black')

# 设置标题和坐标轴标签
ax.set_title('房价地理分布')
ax.set_xlabel('经度（模拟）')
ax.set_ylabel('纬度（模拟）')

# 显示图形
plt.show()